package sslx

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"net/http"
	"strings"
	"time"
)

func CheckSSLCertificate(domain string) (bool, error) {
	// 创建一个自定义的 HTTP 客户端
	client := &http.Client{
		Timeout: 10 * time.Second, // 整个请求的超时时间
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: false, // 禁用证书验证，如果设置为 true 会跳过验证
			},
			DialContext: (&net.Dialer{
				Timeout:   5 * time.Second, // 连接超时时间
				KeepAlive: 30 * time.Second,
			}).DialContext,
			ResponseHeaderTimeout: 5 * time.Second, // 响应头超时时间
			ExpectContinueTimeout: 2 * time.Second, // 100-continue 状态超时时间
		},
	}
	// 发送 HTTP 请求
	resp, err := client.Get("https://" + domain)
	if err != nil {
		// 检查错误是否是 handshake failure
		// if isTLSHandshakeFailure(err) {
		// 	logx.Errorf("CheckSSLCertificate TLS handshake failure detected:%v", err)
		// 	return false, err
		// } else {
		// 	logx.Errorf("CheckSSLCertificate Failed to make request: %v", err)
		// 	return false, nil
		// }
		return false, err
	}
	defer resp.Body.Close()

	// 从响应中获取 TLS 连接状态
	// tlsState := resp.TLS
	// if tlsState != nil {
	// 	for _, cert := range tlsState.PeerCertificates {
	// 		fmt.Println("Certificate Subject:", cert.Subject)
	// 		fmt.Println("Certificate Issuer:", cert.Issuer)
	// 		fmt.Println("Certificate is Valid:", cert.VerifyHostname("gg.connectpro.baby") == nil)
	// 	}
	// } else {
	// 	fmt.Println("TLS connection state is nil")
	// }
	return true, nil
}

// isTLSHandshakeError 判断是否是 TLS handshake failure
// 判断是否是 TLS handshake failure
func isTLSHandshakeFailure(err error) bool {
	// 检查是否是 *net.OpError 类型的错误
	var opErr *net.OpError
	if errors.As(err, &opErr) {
		if opErr.Err != nil {
			// 检查底层错误的字符串信息
			if strings.Contains(opErr.Err.Error(), "handshake failure") ||
				strings.Contains(opErr.Err.Error(), "tls:") {
				return true
			}
		}
	}

	// 检查普通 error 的字符串信息
	if err != nil && strings.Contains(err.Error(), "handshake failure") {
		return true
	}

	return false
}

// CheckSSLCertificateOld 检查域名的 SSL 证书是否有效,缺陷证书处于待验证TXT阶段会误判为成功
func CheckSSLCertificateOld(domain string) (bool, error) {
	// 配置 net.Dialer 以设置连接超时时间
	dialer := &net.Dialer{
		Timeout: 5 * time.Second,
	}

	// 使用 tls.DialWithDialer 创建连接
	conn, err := tls.DialWithDialer(dialer, "tcp", domain+":443", &tls.Config{
		ServerName:         domain,
		InsecureSkipVerify: true, // 跳过验证
	})
	if err != nil {
		return false, fmt.Errorf("failed to connect: %w", err)
	}
	defer conn.Close()

	// 获取 TLS 连接状态和证书信息
	connState := conn.ConnectionState()
	if len(connState.PeerCertificates) == 0 {
		return false, fmt.Errorf("no SSL certificate found for %s", domain)
	}

	// 获取并打印证书详细信息
	cert := connState.PeerCertificates[0]
	// fmt.Printf("Certificate for %s:\n", domain)
	// fmt.Printf("  Issuer: %s\n", cert.Issuer)
	// fmt.Printf("  Valid from: %s\n", cert.NotBefore)
	// fmt.Printf("  Valid until: %s\n", cert.NotAfter)
	// fmt.Printf("  DNS Names: %v\n", cert.DNSNames)

	// 检查证书是否在有效期内
	if time.Now().Before(cert.NotBefore) || time.Now().After(cert.NotAfter) {
		return false, fmt.Errorf("certificate is not valid for the current date domain:%s", domain)
	}

	return true, nil
}
